package main

import (
	"flag"
	"log"
	"os"
	"periph.io/x/conn/v3/gpio"
	"periph.io/x/conn/v3/gpio/gpioreg"
	"periph.io/x/conn/v3/physic"
	"periph.io/x/conn/v3/spi"
	"periph.io/x/conn/v3/spi/spireg"
	"periph.io/x/host/v3"
	"time"
)

var cva, busy, cs, reset gpio.PinIO
var Connect spi.Conn
var low = gpio.Low
var high = gpio.High

var o = flag.Bool("o", false, "tcp://host:port")

func regGpio() {
	//gpio1
	cva = gpioreg.ByName("22")
	if cva == nil {
		log.Printf("leenux- gpioreg gpio1 error\n")
		return
	}

	//gpio27
	cs = gpioreg.ByName("123")
	if cs == nil {
		log.Printf("leenux- gpioreg gpio27 error\n")
		return
	}

	//gpio28
	busy = gpioreg.ByName("126")
	if busy == nil {
		log.Printf("leenux- gpioreg gpio28 error\n")
		return
	}

	//if err := busy.In(gpio.Float, gpio.BothEdges); err != nil {
	//	log.Printf("leenux- In gpio28 low error: %v\n", err)
	//	return
	//}

	//gpio29
	reset = gpioreg.ByName("131")
	if reset == nil {
		log.Printf("leenux- gpioreg gpio29 error\n")
		return
	}

}

func digitalWrite(io gpio.PinIO, level gpio.Level) error {
	err := io.Out(level)
	//time.Sleep(time.Microsecond)
	return err
}

func pulse(io gpio.PinIO) error {
	if err := digitalWrite(io, high); err != nil {
		return err
	}
	if err := digitalWrite(io, high); err != nil {
		return err
	}
	if err := digitalWrite(io, low); err != nil {
		return err
	}
	if err := digitalWrite(io, low); err != nil {
		return err
	}

	return nil
}

func Reset() error {
	if err := digitalWrite(cs, low); err != nil {
		return err
	}
	if err := digitalWrite(cva, low); err != nil {
		return err
	}
	if err := digitalWrite(reset, low); err != nil {
		return err
	}
	if err := digitalWrite(reset, high); err != nil {
		return err
	}
	if err := digitalWrite(reset, low); err != nil {
		return err
	}
	return nil
}

func main() {
	flag.Parse()

	if _, err := host.Init(); err != nil {
		log.Printf("leenux- host.Init: %v\n", err)
		return
	}

	regGpio()
	log.Printf("leenux- gpio init\n")

	s, err := spireg.Open("/dev/spidev3.0")
	if err != nil {
		log.Printf("leenux- open dev error:%v\n", err)
		return
	}
	defer s.Close()
	Connect, err = s.Connect(physic.MegaHertz*5, spi.Mode2, 16)
	if err != nil {
		log.Printf("leenux- connect dev error:%v\n", err)
		return
	}

	log.Printf("leenux- Connect is %v\n", Connect)

	if err := Reset(); err != nil {
		log.Printf("leenux- reset error:%v\n", err)
		return
	}
	log.Printf("leenux- Reset ok\n")

	p := []spi.Packet{
		{
			R: make([]byte, 16),
		},
	}

	for range time.NewTicker(500 * time.Microsecond).C {
		//nowLast := time.Now()
		if err := pulse(cva); err != nil {
			log.Printf("leenux- pulse error: %v\n", err)
			return
		}
		//log.Printf("leenux- pulse ok\n")

		if err := digitalWrite(cs, low); err != nil {
			log.Printf("leenux- digitalWrite error: %v\n", err)
			return
		}
		//log.Printf("leenux- cs set low ok\n")

		if err := busy.In(gpio.Float, gpio.NoEdge); err != nil {
			log.Printf("leenux- In gpio28 low error: %v\n", err)
			return
		}
		//log.Printf("leenux- Waiting for busy\n")

		busy.WaitForEdge(-1)
		//log.Printf("leenux- In gpio28 is: %v\n", busy.Read())
		if err := Connect.TxPackets(p); err != nil {
			log.Printf("leenux- TxPackets err %v\n", err)
		}
		//log.Printf("leenux- time sum:%v\n", time.Since(nowLast).Microseconds())
		log.Printf("leenux- Get read pkg len:%v   data:%v\n", len(p), p[0].R)
		//log.Printf("leenux- Get read pkg len:%v   data:%v\n", len(read), read)

	}

	b := make([]byte, 1)
	os.Stdin.Read(b)
}
